package manual100;

import java.util.*;
import java.io.*;
import java.util.Map.*;

import zclTool.*;

class Case {
	String name;
	double f[] = new double[30];
	int pos;

	public String toString(int fid) {
		String res = "";
		for (int i = 0; i < fid; i++) {
			res += f[i] + ",";
		}
		if (pos == 1) {
			res += "+";
		} else {
			res += "-";
		}
		return res;
	}
	
	public String toSVMString(int fid) {
		String res = "";
		if (pos == 1) {
			res += "1 ";
		} else {
			res += "-1 ";
		}
		for (int i = 0; i < fid; i++) {
			int id = i+1;
			res += id+":"+f[i] + " ";
		}

		return res;
	}
}

public class H_2DecisionTreeFeatures {

	// merge the feature files into decision tree feature file
	// Input: (1) candidates (2) positive cases; (3) feature files 1, 2, 3, ...
	// Output: *.data; *.name
	/**
	 * @param args
	 */
	static HashMap<String, Case> cases = new HashMap<String, Case>();

	static int CurFeaId = 0;

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		String candidate_file = args[0];
		String positive_file = args[1];
		String output_file = args[2];
		List<String> feafiles = new ArrayList<String>();
		for (int i = 3; i < args.length; i++) {
			feafiles.add(args[i]);
		}

		loadCandidate(candidate_file);
		loadPos(positive_file);
		for (int i = 0; i < feafiles.size(); i++) {
			loadOneFea(feafiles.get(i));
		}
		store(output_file);

	}

	public static void loadCandidate(String file) throws Exception {
		DelimitedReader dr = new DelimitedReader(file);
		String[] line;
		while ((line = dr.read()) != null) {
			String ib = line[0].toLowerCase();
			String fb = line[1].toLowerCase();
			String name = ib + "\t" + fb;
			Case c = new Case();
			c.name = name;
			c.pos = -1;
			cases.put(name, c);
		}
		dr.close();
	}

	public static void loadPos(String file) throws Exception {
		DelimitedReader dr = new DelimitedReader(file);
		String[] line;
		while ((line = dr.read()) != null) {
			String ib = line[0].toLowerCase();
			String fb = line[1].toLowerCase();
			String name = ib + "\t" + fb;
			Case c = cases.get(name);
			if (c != null) {
				c.pos = 1;
			}
		}
		dr.close();
	}

	public static void loadOneFea(String file) throws Exception {
		
		DelimitedReader dr = new DelimitedReader(file);
		String[] line;
		int addedFea = 0;
		while ((line = dr.read()) != null) {
			String ib = line[0].toLowerCase();
			String fb = line[1].toLowerCase();
			String name = ib + "\t" + fb;
			Case c = cases.get(name);
			int startFea = CurFeaId;
			addedFea =  line.length-2;
			for (int i = 2; i < line.length; i++) {
				double a = Double.parseDouble(line[i]);
				c.f[startFea] = a;
				startFea++;
			}
		}
		CurFeaId+=addedFea;
		dr.close();
	}

	public static void store(String file) throws Exception {
		//10 cross validation
		List<String>posstr = new ArrayList<String>();
		List<String>negstr = new ArrayList<String>();
		StringBuffer namebuf = new StringBuffer();
		//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(datafile), "utf-8");
		Iterator<Entry<String, Case>> it = cases.entrySet().iterator();
		while (it.hasNext()) {
			Entry<String, Case> e = it.next();
			Case c = e.getValue();
			if(c.pos == 1){
				posstr.add(c.toString(CurFeaId));
				//osw.write(c.toString(CurFeaId) + "\n");
			}else{
				if(Math.random()<0.01){
					negstr.add(c.toString(CurFeaId));
					//osw.write(c.toString(CurFeaId) + "\n");
				}
			}
		}
		//osw.close();

		//osw = new OutputStreamWriter(new FileOutputStream(namefile), "utf-8");
		namebuf.append("+, -.\n\n");
		//osw.write("+, -.\n\n");
		for (int i = 0; i < CurFeaId; i++) {
			namebuf.append("f[" + i + "]: continuous.\n");
			//osw.write("f[" + i + "]: continuous.\n");
		}
		//osw.close();
		//10 cross validation
		int CVSIZE=5;
		double testPosSize = posstr.size()*1.0/CVSIZE;
		double testNegSize = negstr.size()*1.0/CVSIZE;
		for(int k = 0;k<CVSIZE;k++){
			OutputStreamWriter osw_train = new OutputStreamWriter(new FileOutputStream(file+"."+k+".data"), "utf-8");
			OutputStreamWriter osw_test = new OutputStreamWriter(new FileOutputStream(file+"."+k+".test"), "utf-8");
			OutputStreamWriter osw_name = new OutputStreamWriter(new FileOutputStream(file+"."+k+".names"), "utf-8");
			for(int i = 0;i<posstr.size();i++){
				if(i>=testPosSize*k && i<testPosSize*(k+1)){
					osw_test.write(posstr.get(i)+"\n");
				}else{
					osw_train.write(posstr.get(i)+"\n");
				}
			}
			for(int i=0;i<negstr.size();i++){
				if(i>=testNegSize*k && i<testNegSize*(k+1)){
					osw_test.write(negstr.get(i)+"\n");
				}else{
					osw_train.write(negstr.get(i)+"\n");
				}
			}		
			osw_name.write(namebuf.toString());
			
			osw_name.close();
			osw_train.close();
			osw_test.close();
			
		}

	}

}
